﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Controls;

namespace Alfa.Common.ValidationRules {
	public class NumericRangeValidationRule : ValidationRuleBase {
		public NumericRangeValidationRule( ) { }

		public bool Nullable { get; set; }
		public long? Min { get; set; }
		public long? Max { get; set; }

		public override ValidationResult Validate(object value, CultureInfo cultureInfo) {
			long longNumber = 0;

			if (Min > Max) // Does Min is greater than Max?
				throw new Exception("Min range criteria cannot be greater than Max range criteria.");
			if (value == null) {
				if (!this.Nullable)
					return this.ParseError(false, Messages.NotANumber);
			} else if (value is sbyte) { // Does value is already sbyte?
				longNumber = (sbyte)value;
			} else if (value is byte) { // Does value is already byte?
				longNumber = (byte)value;
			} else if (value is short) { // Does value is already short?
				longNumber = (short)value;
			} else if (value is ushort) { // Does value is already ushort?
				longNumber = (ushort)value;
			} else if (value is int) { // Does value is already int?
				longNumber = (int)value;
			} else if (value is uint) { // Does value is already uint?
				longNumber = (uint)value;
			} else if (value is long) { // Does value is already long?
				longNumber = (long)value;
				//} else if (value is ulong) { // Does value is already ulong?
				//	longNumber = (ulong)value;
			} else if (value is string) { // Does value is string?
				if (((string)value).Length > 0) {
					if (Min <= int.MaxValue && Max <= int.MaxValue) { // Can value be int or long?
						int intNumber = 0;
						if (!int.TryParse((string)value, out intNumber)) { // Does value is int?
							if (!long.TryParse((string)value, out longNumber)) // Does value is long?
								return this.ParseError(false, Messages.NotANumber);
						} else
							longNumber = intNumber; // Set numer to check
					} else {
						if (!long.TryParse((string)value, out longNumber)) // Does value is long?
							return this.ParseError(false, Messages.NotANumber);
					}
				} else if (!this.Nullable)
					return this.ParseError(false, Messages.NotANumber);
			} else { // Value can not be any numeric type
				throw new ArgumentException(this.GetType( ).ToString( ) + " validator can not validate provided value (Type " + (value != null ? value.GetType( ).ToString( ) : "null") + " is not supported)!");
			}

			if ((Min.HasValue && longNumber < Min) || (Max.HasValue && longNumber > Max)) { // Is number in range?
				return this.ParseError(false, string.Format(Messages.PleaseEnterANumberInTheRange, (Min.HasValue ? Min.ToString( ) : "-∞"), (Max.HasValue ? Max.ToString( ) : "∞")));
			} else {
				return this.ParseError(true, null);
			}
		}
	}
}
